package com.ahp.dao.impl;

import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.ahp.dao.GenericDAO;
import com.ahp.util.PageList;
import com.ahp.util.Pages;

/**
 * @author 李曉娜
 *
 * @param <T>
 * @param <PK>
 */
public class GenericDAOImpl<T, PK extends Serializable> extends HibernateDaoSupport implements GenericDAO<T, PK>{

	private static final Log log = LogFactory.getLog(GenericDAOImpl.class);
	private Class<T> clazz;

	public GenericDAOImpl(Class<T> clazz) {
		this.clazz = clazz;
	}

	/**
	 * {@inheritDoc}
	 */
	public List<T> getAll() {
		return this.getHibernateTemplate().find("from " + this.clazz.getSimpleName());
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean exists(PK id) {
		T entity = (T) this.getHibernateTemplate().get(this.clazz.getName(), id);
		return entity != null;
	}

	/**
	 * @param queryParams
	 * @return
	 * @date:Sep 5, 2009
	 * @author: 李晓娜
	 */
	public List<T> findByProperty(Map<String, Object> queryParams) {
		Iterator<String> i = queryParams.keySet().iterator();
		StringBuffer hql = new StringBuffer();
		hql.append("from " + this.clazz.getSimpleName() + " as model where ");
		while (i.hasNext()) {
			String key = i.next();
			hql.append("model.");
			hql.append(key);
			hql.append("=?");
		}
		log.debug("finding " + this.clazz.getSimpleName() + " instance! hql:"
				+ hql);
		try {
			Query queryObject = this.getSession().createQuery(hql.toString());
			while (i.hasNext()) {
				queryObject.setParameter(0, queryParams.get(i.next()));
			}
			return queryObject.list();
		} catch (RuntimeException re) {
			log.error("find by property name failed", re);
			return null;
		}
	}

	/**
	 * @param hql
	 * @param args
	 * @return
	 * @date:Sep 5, 2009
	 * @author: 李晓娜
	 */
	public List<T> queryInfo(String hql, final Object... args) {
		return this.getHibernateTemplate().find(hql, args);
	}

	/**
	 * @param pages
	 * @param hql
	 * @param args
	 * @return
	 * @date:Sep 5, 2009
	 * @author: 李晓娜
	 */
	public PageList pageQuery(Pages pages, String hql, final Object... args) {
		String querySQL = hql;
		Query query = this.getSession().createQuery(querySQL);
		for (int i = 0; i < args.length; i++) {
			query.setParameter(i, args[i]);
		}
		return pages.pageList(query, pages);
	}
}
